package crypto.GM;

import org.apache.commons.codec.DecoderException;
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.util.encoders.Hex;

import java.io.IOException;
import java.math.BigInteger;
import java.util.Base64;

public class SM2Test {

    private static String privateKey;
    private static Boolean skipSM2;

    public static String decrypt(String cipherData) throws InvalidCipherTextException {
        //这是对main方法的缩写
        privateKey = "";
        skipSM2 = true;

        if (skipSM2){
            return cipherData;
        }

        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());

        byte[] cipherDataByte = Hex.decode(cipherData);
        BigInteger privateKeyD = new BigInteger(privateKey, 16);
        ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);
        SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
        sm2Engine.init(false, privateKeyParameters);
        byte[] arrayOfBytes = Base64.getDecoder().decode(sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length));
        return new String(arrayOfBytes);
    }


    public static void main(String[] args) throws DecoderException, InvalidCipherTextException, IOException {
//      生成密钥对
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());

//
//JS加密产生的密文
        String cipherData = "04cbc583c19f5f25e1722eaa9fc4f18d3ed280394212fbff138ebb90917081100dd93d8761c167b7dd57d54f800a6aa54d1ded43dc16659c6822125233356eadb29c02f583cf10c41fb7d3cab6445f344bf04bb7778c11c4d90985c34709b6939a3d9435116243dc125b9015e6c65f2cc0";
        byte[] cipherDataByte = org.apache.commons.codec.binary.Hex.decodeHex(cipherData);

        String publicKey = "B9C9A6E04E9C91F7BA880429273747D7EF5DDEB0BB2FF6317EB00BEF331A83081A6994B8993F3F5D6EADDDB81872266C87C018FB4162F5AF347B483E24620207";

//刚才的私钥Hex，先还原私钥
        //String privateKey = "a2081b5b81fbea0b6b973a3ab6dbbbc65b1164488bf22d8ae2ff0b8260f64853";
        String privateKey = "00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5";
        BigInteger privateKeyD = new BigInteger(privateKey, 16);


        ECPrivateKeyParameters ecPrivateParam = new ECPrivateKeyParameters(privateKeyD, domainParameters);

//用私钥解密
        SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
        sm2Engine.init(false, ecPrivateParam);

//processBlock得到Base64格式，记得解码
        byte[] arrayOfBytes = Base64.getDecoder().decode(sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length));
        //byte[] arrayOfBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);

//得到明文：SM2 Encryption Test
        String data = new String(arrayOfBytes);
        System.out.println(data);

        System.out.println(org.apache.commons.codec.binary.Hex.encodeHexString("s".getBytes()));
    }
}
